<template>
  <div class="flex ml-20px">
    <div class="tableManage w-100%">
      <ContentWrap>
        <!-- 搜索区域 -->
        <div class="search-form">
          <Search
            :schema="allSchemas.searchSchema"
            @reset="setSearchParams"
            @search="setSearchParams"
          />
        </div>

        <ElDivider />

        <!-- 操作按钮区域 -->
        <div class="mb-10px">
          <BaseButton class="opBtn" size="" type="primary" @click="AddAction">
            新增
          </BaseButton>
          <!-- 导入功能 -->
          <el-upload
            ref="uploadRef"
            class="opBtn-upload"
            :auto-upload="false"
            :show-file-list="false"
            :accept="'.xlsx,.xls'"
            :on-change="handleFileSelect"
          >
            <BaseButton class="opBtn" size="" type="primary"
              >导入数据</BaseButton
            >
          </el-upload>
          <BaseButton type="primary" @click="exportActionExcel">
            下载模板
          </BaseButton>
        </div>

        <!-- 数据表格 -->
        <Table
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :columns="allSchemas.tableColumns"
          :data="dataList"
          :loading="loading"
          @register="tableRegister"
          :pagination="{ total }"
        />
      </ContentWrap>
    </div>

    <!-- 新增/编辑/查看对话框 -->
    <Dialog width="65%" v-model="dialogVisible" :title="dialogTitle">
      <!-- 表单组件（新增/编辑时显示） -->
      <Write
        class="opWrite"
        v-if="actionType !== 'detail'"
        ref="writeRef"
        :form-schema="allSchemas.formSchema"
        :current-row="currentRow"
      />

      <!-- 详情组件（查看时显示） -->
      <Detail
        v-if="actionType === 'detail'"
        :detail-schema="allSchemas.detailSchema"
        :current-row="currentRow"
      />

      <!-- 对话框底部按钮 -->
      <template #footer>
        <BaseButton
          v-if="actionType !== 'detail'"
          type="primary"
          :loading="saveLoading"
          @click="save"
        >
          保存
        </BaseButton>
        <BaseButton @click="dialogVisible = false">关闭</BaseButton>
      </template>
    </Dialog>

    <Dialog v-model="resultDialogVisible" :title="importTitle" width="50%">
      <div class="import-result">
        <div
          class="import-result-container"
          :style="{ height: resultContainerHeight }"
        >
          <div
            v-for="(error, index) in tabs1"
            :key="index"
            class="demo-tabs full-height-tabs"
          >
            <!-- 移除外层的 flex 布局，使用简单的固定高度 -->
            <div class="error-content-wrapper">
              <div class="error-item">
                <h4 class="mb-10px">{{ error.dataRow }}:</h4>
                <p class="mb-5px" v-for="(item, i) in error.errors" :key="i">
                  {{ item }}
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <BaseButton type="primary" @click="resultDialogVisible = false">
          确定
        </BaseButton>
      </template>
    </Dialog>
  </div>
</template>

<script setup lang="tsx">
import { directAxios } from "@/axios/index";
import { ref, unref, reactive, defineProps, withDefaults, onMounted, onUnmounted } from "vue";
import { ContentWrap } from "@/components/ContentWrap";

import { Table } from "@/components/Table";
import {
  ElMessage,
  ElMessageBox,
  ElUpload,
  UploadFile,
  UploadInstance,
} from "element-plus";
import * as XLSX from "xlsx";
import { useTable } from "@/hooks/web/useTable";
import { Search } from "@/components/Search";
import Write from "./components/emptyPacketManagementWrite.vue";
import Detail from "./components/emptyPacketManagementDetail.vue";
import { Dialog } from "@/components/Dialog";
import { CrudSchema, useCrudSchemas } from "@/hooks/web/useCrudSchemas";
import { BaseButton } from "@/components/Button";
import { Edit, View, Delete } from "@element-plus/icons-vue";
import axios from "axios";
import { useDictionaryStore } from "@/store/modules/dictionaryStore";

const dictionaryStore = useDictionaryStore();



// 添加响应式高度控制
const resultContainerHeight = ref("400px"); // 默认高度
const errorContentHeight = ref("300px"); // 错误内容区域高度

const calculateHeights = () => {
  const windowHeight = window.innerHeight;
  const dialogHeight = windowHeight * 0.7;
  resultContainerHeight.value = `${dialogHeight - 120}px`;
  errorContentHeight.value = `${dialogHeight - 250}px`; // 调整这个值，为 tabs 头部留出空间
};
// ============ 响应式数据定义 ============

// 表格相关状态
const { tableRegister, tableState, tableMethods } = useTable({
  /**
   * 获取表格数据的API
   */
  fetchDataApi: async () => {
    const { pageSize, currentPage } = tableState;
    const res = await "/cExcludedCatalog/page".get({
      pageNum: unref(currentPage),
      pageSize: unref(pageSize),
      ...unref(searchParams),
    });

    return {
      list: res.data.records || [],
      total: res.data.total || 0,
    };
  },
});

const { total, loading, dataList, pageSize, currentPage } = tableState;
const { getList, getElTableExpose, delList } = tableMethods;

// 搜索参数
const searchParams = ref({
  classificationCode: "",
});

// 对话框相关状态
const dialogVisible = ref(false);
const dialogTitle = ref("");
const currentRow = ref();
const actionType = ref("");

// 加载状态
const saveLoading = ref(false);
const importLoading = ref(false);

// 组件引用
const writeRef = ref<ComponentRef<typeof Write>>();
const uploadRef = ref<UploadInstance>();

// 导入相关
const selectedFile = ref<File | null>(null);

// ============ CRUD表结构配置 ============
/**
 * 处理类别选择变化
 * @param value 选中的值数组
 * @param selectedOptions 选中的选项对象数组
 */

const getCascaderObj = (val, opt) => {
  return val.map(function (value, index, array) {
    for (var itm of opt) {
      if (itm.code == value) {
        opt = itm.children;
        return itm;
      }
    }
    return null;
  });
};

const handleCategoryChange = (value) => {
  console.log(value);

  const selectedOptions = getCascaderObj(
    value,
    dictionaryStore.dictionaries.get(
      dictionaryStore.DICTIONARY_TYPES.COM_CLASSIFICATION
    )
  );
  if (!currentRow.value) {
    currentRow.value = {};
  }

  // // // 清空之前的分类数据
  currentRow.value.classification1 = "";
  currentRow.value.classification2 = "";
  currentRow.value.classification3 = "";
  currentRow.value.classificationCode = "";
  currentRow.value.category = value;
  currentRow.value.classificationCode =
    selectedOptions[selectedOptions.length - 1].code;
  // // // 根据选中的层级设置对应的分类字段
  if (selectedOptions.length > 0) {
    currentRow.value.classification1 = selectedOptions[0]?.text || "";
  }
  if (selectedOptions.length > 1) {
    currentRow.value.classification2 = selectedOptions[1]?.text || "";
  }
  if (selectedOptions.length > 2) {
    currentRow.value.classification3 = selectedOptions[2]?.text || "";
  }
};
// 类别
const classificationOptions = computed(() => {
  return (
    dictionaryStore.dictionaries.get(
      dictionaryStore.DICTIONARY_TYPES.COM_CLASSIFICATION
    ) || []
  );
});
/**
 * CRUD表结构配置
 * 定义优选目录管理的表格列、搜索表单、编辑表单的字段配置
 */
const crudSchemas = reactive<CrudSchema[]>([
  {
    field: "selection",
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    table: { type: "selection", hidden: true },
  },
  {
    field: "index",
    label: "序号",
    form: { hidden: true },
    search: { hidden: true },
    detail: { hidden: true },
    table: { type: "index" },
  },
  {
    field: "aviationModel",
    label: "工程名称",
    form: {
      formItemProps: {
        rules: [
          {
            required: true,
            message: "请输入工程名称",
          },
          { pattern: /^(?!\s*$)(?!\/+$).+$/, message: "请输入工程名称" },
        ],
      },
      componentProps: { placeholder: "请输入工程名称" },
    },
    search: {
      component: "Input",
      label: "工程名称",

      hidden: false,
      componentProps: { placeholder: "工程名称" },
    },
  },
  {
    field: "classificationCode",
    width: 100,
    label: "分类代码",
    form: {
      componentProps: {
        placeholder: "分类代码将自动生成",
        disabled: true,
      },
      formItemProps: {
        rules: [
          {
            required: true,
            message: "请输入分类代码",
          },
        ],
      },
    },
    search: {
      hidden: true,
    },
  },
  {
    field: "category",
    label: "类别",
    search: {
      label: "类别",
      component: "Cascader",
      componentProps: {
        placeholder: "类别",
        options: classificationOptions, // 使用计算属性
        // 配置自定义的 label 和 value 字段
        props: {
          checkStrictly: false,
          emitPath: true,
          label: "text", // 自定义 label 字段
          value: "code", // 自定义 value 字段
          // expandTrigger: 'hover'
        },
      },
    },

    form: {
      component: "Cascader",
      formItemProps: {
        rules: [
          { required: true, message: "请选择类别" },
          // { pattern: /^[0-9]{11}$/, message: "请输入正确的联系方式" },
        ],
      },

      componentProps: {
        placeholder: "请选择类别",
        options: classificationOptions, // 使用计算属性
        // 配置自定义的 label 和 value 字段
        props: {
          checkStrictly: false,
          emitPath: true,
          label: "text", // 自定义 label 字段
          value: "code", // 自定义 value 字段
          // expandTrigger: 'hover'
        },
        onChange: (value: any[]) => {
          handleCategoryChange(value);
        },
      },
    },
    detail: { hidden: true },
    table: {
      formatter: (row: any) => {
        // 组合分类字段，用 > 分隔，空值用 / 代替
        const parts = [
          row.classification1 || "/",
          row.classification2 || "/",
          row.classification3 || "/",
        ];
        return parts.join(" > ");
      },
    },
  },
  {
    field: "classification1",
    label: "一级类别",
    width: 90,
    search: { hidden: true },
    form: { hidden: true },
    table: { hidden: true },
  },
  {
    field: "classification2",
    label: "二级类别",
    width: 90,
    search: { hidden: true },
    form: { hidden: true },
    table: { hidden: true },
  },
  {
    field: "classification3",
    label: "三级类别",
    width: 90,
    search: { hidden: true },
    form: { hidden: true },
    table: { hidden: true },
  },
  {
    field: "componentName",
    label: "元器件名称",
    width: 150,
    search: {
      component: "Input",
      label: "元器件名称",
      hidden: false,
      componentProps: { placeholder: "元器件名称" },
    },

    form: {
      component: "Input",
      formItemProps: {
        rules: [
          {
            required: true,
            message: "请输入元器件名称",
          },
          { pattern: /^(?!\s*$)(?!\/+$).+$/, message: "请输入元器件名称" },
        ],
      },
      componentProps: { placeholder: "请输入元器件名称" },
    },
  },
  {
    field: "specification",
    label: "型号规格",
    width: 150,
    search: {
      component: "Input",
      label: "型号规格",
      hidden: false,
      componentProps: { placeholder: "型号规格" },
    },
    form: {
      component: "Input",
      formItemProps: {
        rules: [
          {
            required: true,
            message: "请输入型号规格",
          },
          { pattern: /^(?!\s*$)(?!\/+$).+$/, message: "请输入元器件名称" },
        ],
      },
      componentProps: { placeholder: "请输入型号规格" },
    },
  },
  {
    field: "flag",
    label: "状态",
    width: 150,
    search: {
      component: "Select",
      label: "状态",
      hidden: false,
      componentProps: {
        placeholder: "状态",
        options: [
          {
            label: "W",
            value: "W",
          },
          {
            label: "K",
            value: "K",
          },
          {
            label: "B",
            value: "B",
          },
        ],
      },
    },
    form: {
      component: "Select",
      formItemProps: {
        rules: [
          {
            required: true,
            message: "请选择状态",
          },
          { pattern: /^(?!\s*$)(?!\/+$).+$/, message: "请选择状态" },
        ],
      },
      componentProps: {
        placeholder: "请选择状态",
        options: [
          {
            label: "W",
            value: "W",
          },
          {
            label: "K",
            value: "K",
          },
          {
            label: "B",
            value: "B",
          },
        ],
      },
    },
  },
  {
    field: "dataSource",
    label: "数据来源",
    width: 120,
    search: {
      hidden: false,
      component: "Input",
      label: "数据来源",

      componentProps: { placeholder: "数据来源" },
    },
    detail: { span: 12 },
    form: {
      component: "Input",

      colProps: { span: 12 },
      componentProps: { placeholder: "请输入数据来源" },
    },
  },
  {
    field: "manufacturer",
    label: "生产厂商",

    search: {
      hidden: false,
      component: "Input",
      label: "生产厂商",

      componentProps: { placeholder: "生产厂商" },
    },
    detail: { span: 12 },
    form: {
      component: "Input",
      formItemProps: {
        rules: [
          {
            required: true,
            message: "请输入生产厂商",
          },
          { pattern: /^(?!\s*$)(?!\/+$).+$/, message: "请输入生产厂商" },
        ],
      },
      colProps: { span: 12 },
      componentProps: { placeholder: "请输入生产厂商" },
    },
  },

  {
    field: "remarks",
    label: "备注",
    width: 90,
    search: { hidden: true },
    detail: { span: 24 },
    form: {
      component: "Input",
      componentProps: {
        type: "textarea",
        rows: 3,
        placeholder: "请输入备注信息",
      },
      colProps: { span: 24 },
    },
    table: { hidden: true },
  },
  {
    field: "action",
    label: "操作",
    fixed: "right",
    form: { hidden: true },
    detail: { hidden: true },
    search: { hidden: true },
    table: {
      width: 170,
      fixed: "right",
      slots: {
        default: (data: any) => {
          const row = data.row;
          return (
            <>
              <div style="display:flex;color: var(--el-color-primary)">
                <div
                  class="flex-1 cursor-pointer"
                  onClick={() => action(row, "edit")}
                >
                  <el-icon>
                    <Edit />
                  </el-icon>
                  编辑
                </div>
                <div
                  class="flex-1 cursor-pointer"
                  onClick={() => action(row, "detail")}
                >
                  <el-icon>
                    <View />
                  </el-icon>
                  查看
                </div>
                <div class="flex-1 cursor-pointer" onClick={() => delData(row)}>
                  <el-icon>
                    <Delete />
                  </el-icon>
                  删除
                </div>
              </div>
            </>
          );
        },
      },
    },
  },
]);

// 生成CRUD相关的所有schema
const { allSchemas } = useCrudSchemas(crudSchemas);

// ============ 方法定义 ============

/**
 * 设置搜索参数并刷新表格
 * @param params 搜索参数
 */
const setSearchParams = (params: any) => {
  currentPage.value = 1;
  searchParams.value = params;
  searchParams.value.classificationCode =
    params.category?.[params.category.length - 1] || "";
  getList();
};

/**
 * 新增操作
 */
const AddAction = () => {
  dialogTitle.value = "新增";

  currentRow.value = undefined;
  dialogVisible.value = true;
  actionType.value = "";
};

/**
 * 删除数据
 * @param row 要删除的行数据
 */
const delData = async (row?: any) => {
  const params = new URLSearchParams();
  params.append("id", row?.id);

  ElMessageBox.confirm("是否确认删除?", "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      const params = {
        id: row?.id,
      };
      const res = await directAxios.post("/cExcludedCatalog/delete", params, {
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        transformRequest: [
          (data) => {
            return data.toString();
          },
        ],
      });

      if (res.code === 200) {
        ElMessage.success("删除成功");
        getList();
      }
    })
    .catch(() => {});
};

/**
 * 行操作处理（编辑/查看）
 * @param row 行数据
 * @param type 操作类型：'edit' | 'detail'
 */
const action = (row, type: string) => {
  dialogTitle.value = type === "edit" ? "编辑" : "详情";
  actionType.value = type;
  row.classificationCode === undefined ||
  row.classificationCode == "" ||
  row.classificationCode == null
    ? (row.classificationCode = "")
    : row.classificationCode;

  const data =
    row.classificationCode.length == 8
      ? [
          row.classificationCode.slice(0, 4) || "",
          row.classificationCode.slice(0, 6) || "",
          row.classificationCode || "",
        ]
      : row.classificationCode.length == 6
        ? [
            row.classificationCode.slice(0, 4) || "",
            row.classificationCode.slice(0, 6) || "",
          ]
        : [row.classificationCode.slice(0, 4) || ""];
  currentRow.value = {
    ...row,
    category: data,
  };
  dialogVisible.value = true;
};

/**
 * 保存表单数据
 */
const save = async () => {
  const write = unref(writeRef);
  const formData = await write?.submit();

  if (formData) {
    saveLoading.value = true;
    try {
      const res = await "/cExcludedCatalog/save".post({
        ...formData,
        category: "",
        classification1: currentRow.value.classification1 || "",
        classification2: currentRow.value.classification2 || "",
        classification3: currentRow.value.classification3 || "",
      });
      if (res) {
        currentPage.value = 1;
        getList();
        ElMessage.success("保存成功");
      }
    } catch (error) {
      console.log(error);
    } finally {
      saveLoading.value = false;
      dialogVisible.value = false;
    }
  }
};

// ============ 导入导出功能 ============

const resultDialogVisible = ref(false);
const importTitle = ref("");
const tabs1 = ref();
/**
 * 验证文件类型
 */
const validateFileType = (file: UploadFile) => {
  if (!file.raw) {
    ElMessage.error("文件不存在");
    return false;
  }

  // 检查文件扩展名
  const fileExtension = file.name.split(".").pop()?.toLowerCase();
  const allowedExtensions = ["xls", "xlsx"];

  if (!fileExtension || !allowedExtensions.includes(fileExtension)) {
    ElMessage.error("文件格式错误！只能上传 .xlsx 或 .xls 格式的Excel文件");
    return false;
  }

  // 检查MIME类型（可选，因为不同浏览器可能识别不同）
  const allowedMimeTypes = [
    "application/vnd.ms-excel",
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "application/vnd.ms-excel.sheet.macroEnabled.12",
    "application/octet-stream", // 某些情况下可能是这个类型
  ];

  // 如果MIME类型不为空且不在允许列表中，给出警告但继续（因为扩展名正确）
  if (file.raw.type && !allowedMimeTypes.includes(file.raw.type)) {
    console.warn("文件MIME类型不匹配，但扩展名正确，继续处理");
  }

  // 限制文件大小（10MB）
  // const maxSize = 10 * 1024 * 1024; // 10MB
  // if (file.size && file.size > maxSize) {
  //   ElMessage.error('文件大小不能超过 10MB');
  //   return false;
  // }

  return true;
};
/**
 * 文件选择验证
 */
const handleFileSelect = (file: UploadFile) => {
  // 验证文件类型
  if (!validateFileType(file)) {
    // 清空文件选择
    if (uploadRef.value) {
      uploadRef.value.clearFiles();
    }
    return false;
  }

  // 文件验证通过，继续处理
  handleFileChange(file);
};
/**
 * 处理文件选择变化事件
 * @param file 上传的文件对象
 */
const handleFileChange = async (file: UploadFile) => {
  ElMessageBox.confirm(
    "该操作会覆盖当前系统下所有WKB数据，确认继续？",
    "提示",
    {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    }
  )
    .then(async () => {
      if (!file.raw) {
        return;
      }

      selectedFile.value = file.raw;
      importLoading.value = true;

      importTitle.value = "正在导入文件，请稍后...";
      try {
        // 调用导入API
        const formData = new FormData();
        formData.append("file", file.raw);
        // formData.append('deviceCode', currentNodeKey.value);

        const res = await "/cExcludedCatalog/importExcel".post(formData, {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        });
        if (res.code == 200) {
          ElMessage.success("导入成功");
          getList(); // 刷新列表
          resultDialogVisible.value = false;
        } else if (res.code == 299) {
          importTitle.value = "导入失败";
          // 验证数据
          tabs1.value = res.data;

          resultDialogVisible.value = true;
          importLoading.value = false;
        }
      } catch (error: any) {
        ElMessage.warning(error.data.msg);
      } finally {
        importLoading.value = false;
        // 清空文件选择
        if (uploadRef.value) {
          uploadRef.value.clearFiles();
        }
        selectedFile.value = null;
      }
    })
    .catch(() => {
      // 用户取消，清空文件选择
      if (uploadRef.value) {
        uploadRef.value.clearFiles();
      }
    });
};

/**
 * 导出数据
 */
const exportActionExcel = async () => {
  const res = await "/cExcludedCatalog/downloadExcelTemplate".get(
    {},
    {
      responseType: "blob", // 指定响应类型为blob用于文件下载
    }
  );

  if (res.status === 200) {
    // ElMessage.success("导出成功");
    await handleFileDownload(res);
    ElMessage.success("导出成功，文件已开始下载");
  } else {
    ElMessage.warning(res.data?.msg || "导出失败");
  }
};

/**
 * 处理文件下载
 * @param res 响应对象
 */
const handleFileDownload = async (res: any) => {
  const blob = new Blob([res.data], {
    type: res.headers["content-type"] || "application/octet-stream",
  });

  // 获取文件名
  const contentDisposition = res.headers["content-disposition"];
  let filename = "dataExport";
  if (contentDisposition) {
    const filenameMatch = contentDisposition.match(/filename="?(.+)"?/);
    if (filenameMatch && filenameMatch.length === 2) {
      filename = decodeURIComponent(filenameMatch[1]);
    }
  }

  // 创建下载链接
  const url = window.URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.setAttribute("download", filename);
  document.body.appendChild(link);
  link.click();

  // 清理资源
  window.URL.revokeObjectURL(url);
  document.body.removeChild(link);
};
// 组件挂载后的调试代码
onMounted(async () => {
  await dictionaryStore.preloadCommonDictionaries();

   calculateHeights();
  window.addEventListener("resize", calculateHeights);
  // 其他初始化逻辑...
});
onUnmounted(() => {
  window.removeEventListener("resize", calculateHeights);
});
</script>

<style scoped lang="less">
:deep(.el-card) {
  height: 100%;
}

.operIcon {
  width: 20px !important;
}

:deep(.el-divider--horizontal) {
  margin: 5px 0 15px 0;
}

.mb-10px {
  display: flex;
}

.opBtn-upload {
  display: inline-block;
  margin: 0 12px;
}
.error-item {
  margin-bottom: 16px;
  padding: 12px;
  background: white;
  border-radius: 4px;
  border: 1px solid rgba(251, 198, 198, 1);
  background-color: rgba(254, 240, 240, 0.5);
  // border-left: 4px solid #f56c6c;

  h4 {
    color: #f56c6c;
    font-weight: bold;
  }

  p {
    // color: #606266;
    margin: 4px 0;
    padding-left: 8px;
    color: #f56c6c;
  }
}
</style>
